package com.ghh.encrypto;

import java.security.AccessController;
import java.security.KeyStore;
import java.security.KeyStore.SecretKeyEntry;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.UnrecoverableEntryException;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.JpsException;
import oracle.security.jps.internal.policystore.JavaPolicyProvider;
import oracle.security.jps.service.keystore.KeyStoreService;
import oracle.security.jps.service.keystore.KeyStoreServiceException;

public class KeyStoreTest {

	static {
		System.setProperty("oracle.security.jps.config", "./jps-config-jse.xml");
		java.security.Policy.setPolicy(new JavaPolicyProvider());
	}

	private static KeyStoreService	ks	= null;

	public KeyStoreTest() {
		super();
	}

	/*
	 * This method performs a non-privileged operation. Either all code in the
	 * call stack must have KeyStoreAccessPermission OR the caller must have the
	 * KeyStoreAccessPermission only and invoke this operation in doPrivileged
	 * block
	 */
	public static void doKeyStoreOperation() {
		doOperation();
	}

	/*
	 * Since this method performs a privileged operation, only current class or
	 * jar containing this class needs KeyStoreAccessPermission
	 */
	public static void doPrivilegedKeyStoreOperation() {
		AccessController.doPrivileged(new PrivilegedAction<String>() {
			public String run() {
				doOperation();
				return "done";
			}
		});
	}

	private static void doOperation() {
		try {
//			ks.deleteKeyStore("keystoreapp", "ks1", null);
			ks.createKeyStore("keystoreapp", "ks1", null, null);
			
//			KeyStore kstore = ks.getKeyStore("keystoreapp", "ks1", null);
			
		} catch (KeyStoreServiceException e) {
			e.printStackTrace();
		}
	}
	
	public static void saveSecretKey(KeyStore kstore, byte[] data) throws Exception {
		DESKeySpec desKeySpec = new DESKeySpec(data);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey mySecretKey = keyFactory.generateSecret(desKeySpec);
		System.out.println(new String(desKeySpec.getKey()));
		// save my secret key
//		javax.crypto.SecretKey mySecretKey;
		KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey);
		kstore.setEntry("secretKeyAlias", skEntry, new KeyStore.PasswordProtection("password".toCharArray()));
		
		ks.persist();
		
//		java.io.FileOutputStream fos = null;
//		try {
//			fos = new java.io.FileOutputStream("newKeyStoreName");
//			ks.store(fos, "password".toCharArray());
//		} finally {
//			if (fos != null) {
//				fos.close();
//			}
//		}
	}
	
	public static void loadSecretKey(KeyStore kstore) throws Exception {
		KeyStore.SecretKeyEntry entry = (SecretKeyEntry) kstore.getEntry("secretKeyAlias", new KeyStore.PasswordProtection("password".toCharArray()));
		SecretKey key = entry.getSecretKey();
//		System.out.println(new String(key.getEncoded()));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		DESKeySpec keyspec = (DESKeySpec) keyFactory.getKeySpec(key, DESKeySpec.class);
		System.out.println(new String(keyspec.getKey()));
	}
	

	public static void main(String args[]) throws Exception {
		try {
			JpsContext ctx = JpsContextFactory.getContextFactory().getContext();
			ks = ctx.getServiceInstance(KeyStoreService.class);
			
			saveSecretKey(ks.getKeyStore("keystoreapp", "ks1", null), "abcdefgh".getBytes());
//			loadSecretKey(ks.getKeyStore("keystoreapp", "ks1", null));
			
			// #1 - this call is in a doPrivileged block
			// #1 - this should succeed.
//			doPrivilegedKeyStoreOperation();

			// #2 - this will also pass since granted all application
			// code necessary permission
			// NOTE: Since this call is not in a doPrivileged block,
			// this call would have failed if KeyStoreAccessPermission
			// wasn't granted to this class.

			/*
			 * doKeyStoreOperation();
			 */

		} catch (Exception je) {
			je.printStackTrace();
		}

	}
}